

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Vector;
import java.util.Arrays;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

public class Partie implements Runnable{
	private Vector<Client> joueurs;
	public int idPartie;
	private Thread thread; 
	//private int posX[];
	//private int posY[];
	//private int rotation;
	private boolean launched;
	private Timer t;
	
	public Partie(Client createur, int idPartie){
		//posX=new int[6];
	//	posY=new int[6];
		launched=false;
		
		t = new Timer (1000, new ActionListener(){
			public void actionPerformed(ActionEvent e){
				//on envoie un message a tous les participants de la partie pour verifier qu'ils sont encore la
				broadcastPartie("hello");
			}
		});
		t.start();

		joueurs = new Vector<Client>();
		joueurs.add(createur);
		createur.setInGame(true);
		this.idPartie = idPartie;
		thread = new Thread(this); 
		thread.start();
	}
	
	public void run(){
		// Contenu du thread
		ByteBuffer buf = ByteBuffer.allocate(1024);
		try{
			while(true){
				for(int i=0 ; i<joueurs.size();i++){
					try{   
						int bytesRead = joueurs.get(i).getSocketChannel().read(buf);
						if(bytesRead>0){
							messageReceivedForParties(joueurs.get(i), buf, bytesRead);
						}
						buf.clear();
					}catch(IOException e){ }
				}
			}
	    }
	    catch (Exception e){ System.out.println(e); }
	}
	
	public void ajouterJoueur(Client nouveauJoueur){
		joueurs.add(nouveauJoueur);
		nouveauJoueur.setInGame(true);
	}
	
	private void sendIdPartie(){
		broadcastPartie("ID/"+idPartie);
	}
	
	
	public void sendListeJoueurPartie(){
		String liste = "listeJoueurPartie/";
		for(int i=0 ; i<joueurs.size() ; i++){
			liste += joueurs.get(i).getPseudo()+"-";
			if(joueurs.get(i).isReady()){
				liste+="true/";
			}
			else {
				liste+="false/";
			}
		}
			
		broadcastPartie(liste);
	}
	
	private void sendListePersoChoisis(){
		String liste = "listePersoChoisis/";
		for(int i=0 ; i<joueurs.size() ; i++){
			if(joueurs.get(i).getPersoChoisi()!=0)
				liste += joueurs.get(i).getPseudo()+"-"+joueurs.get(i).getPersoChoisi()+"/";
		}
		broadcastPartie(liste);
		
	}

	private void messageReceivedForParties(Client emetteur, ByteBuffer message, int nbChar){
		String mesString = new String(message.array());
		String parse[]=mesString.substring(0, nbChar-1).split("/");
		handlingMessage(emetteur, parse);	
		message.clear();
	}
	
	private void handlingMessage(Client emetteur, String parse[]){
		//System.out.println("on recoit (partie) : "+mesString);
		if(parse[0].equals("readyForPartie")){
			broadcastPartie("nouveauJoueurReady/"+emetteur.getPseudo());
			emetteur.setReady(true);
			if (parse.length>1) {
				parse[1]=parse[1].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 1, parse.length));
			}
		}
		if (parse[0].equals("askIdPartie")){
			sendIdPartie();
			if (parse.length>1) {
				parse[1]=parse[1].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 1, parse.length));
			}	
		}
		if(parse[0].equals("askListeJoueurPartie")){
			sendListeJoueurPartie();
			if (parse.length>1) {
				parse[1]=parse[1].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 1, parse.length));
			}
		}
		if(parse[0].equals("askListePersoChoisis")){
			sendListePersoChoisis();
			if (parse.length>1) {
				parse[1]=parse[1].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 1, parse.length));
			}
		}
		if(parse[0].equals("persoChoisi")){
			emetteur.setPersoChoisi(Integer.parseInt(parse[1]));
			broadcastPartie("nouveauPersoChoisi/"+emetteur.getPseudo()+"/"+parse[1]);
			if (parse.length>2) {
				parse[2]=parse[2].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 2, parse.length));
			}
		}
		if(parse[0].equals("lancementPartie")){
			broadcastPartie("lancementPartie");
			emetteur.getServeur().connexion.partieLancee(idPartie);
			launched=true;
				
			if (parse.length>1) {
				parse[1]=parse[1].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 1, parse.length));
			}	
		}
		if (parse[0].equals("position")){
			updatePosition(parse[1], parse[2], parse[3], parse[4]);
			calculNouvellePosition(emetteur, Integer.parseInt(parse[5]));
			if (parse.length>6) {
				parse[6]=parse[6].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 6, parse.length));
			}	
		}
		if(parse[0].equals("readyToPlay")){
			emetteur.setGameLoaded(true);
			verifAllGamersReadyToPlay();
			if (parse.length>1) {
				parse[1]=parse[1].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 1, parse.length));
			}	
		}
		if (parse[0].equals("endOfGame")){
			emetteur.arrive(Integer.parseInt(parse[1]));
			broadcastPartie("joueurArrive/"+emetteur.getPseudo());
			if (parse.length>2) {
				parse[2]=parse[2].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 2, parse.length));
			}
		}
		if (parse[0].equals("bayEaten")){
			broadcastPartie("bayEaten/"+parse[1]);
			if (parse.length>2) {
				parse[2]=parse[2].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 2, parse.length));
			}
		}
		if(parse[0].equals("quitParty")){
			quitParty(emetteur);
			if (parse.length>1) {
				parse[1]=parse[1].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 1, parse.length));
			}
		}
		if(parse[0].equals("animation")){
			broadcastPartieSansEmetteur("animation/"+parse[1]+"/"+parse[2], emetteur);
			if (parse.length>3) {
				parse[3]=parse[3].substring(1);
				handlingMessage(emetteur, Arrays.copyOfRange(parse, 3, parse.length));
			}
		}
	}
	
	public boolean isLaunched() {
		return launched;
	}
	
	private void calculNouvellePosition(Client joueur, int nouvellePositionTerrain){
		joueur.setPositionTerrain(nouvellePositionTerrain);
		int classement=joueurs.size();
		for(int i=0; i<joueurs.size(); i++){
			if(!joueurs.get(i).getPseudo().equals(joueur.getPseudo()) && joueurs.get(i).getPositionTerrain() <= nouvellePositionTerrain && !joueurs.get(i).isArrived()){
				classement--;
			}
		}
		joueur.sendMessage("classement/"+classement);
	}

	public void updatePosition(String idJoueur, String posX, String posY, String rotation){
		int id=Integer.parseInt(idJoueur);
		//this.posX[id-1]=Integer.parseInt(posX);
		//this.posY[id-1]=Integer.parseInt(posY);
		//this.rotation=Integer.parseInt(rotation);
		broadcastPartie("position/"+id+"/"+posX+"/"+posY+"/"+rotation);
	}
	
	public void broadcastPartie(String message){
		for(int i=0 ; i<joueurs.size() ; i++){
			joueurs.get(i).sendMessage(message);
		}
	}
	
	public void broadcastPartieSansEmetteur(String message, Client emetteur){
		for(int i=0 ; i<joueurs.size() ; i++){
			if(emetteur.getIdJoueur() != joueurs.get(i).getIdJoueur())
				joueurs.get(i).sendMessage(message);
		}
	}

	public Vector<Client> getJoueurs() {
		return joueurs;
	}
	
	public void supprimerJoueur(Client joueur){
		joueurs.remove(joueur);
	}
	
	public void verifAllGamersReadyToPlay(){
		boolean allReady = true;
		for(int i=0 ; i<joueurs.size() ; i++){
			if(joueurs.get(i).isGameLoaded() == false)
				allReady = false;
		}
		if(allReady == true){
			broadcastPartie("AllGamersReadyToPlay/");
		}
	}
	
	public void quitParty(Client joueur){
		joueur.getServeur().connexion.retirerJoueurPartie(joueur, idPartie);
		joueur.setInGame(false);
		joueur.setReady(false);
		joueur.setGameLoaded(false);
		joueur.setPositionTerrain(0);
		joueur.setPersoChoisi(0);
		joueur.setNotArrived();
		joueurs.remove(joueur);
		if(joueurs.isEmpty())
			joueur.getServeur().removePartie(this);
	}
}
